enum IpAddKind {
    V4,
    V6,
}

struct IpAddr {
    kind: IpAddKind,
    address: String,
}

// 2.rustlang suggestion
enum IpAddr2 {
    V4(String),
    V6(String),
}

// 3.different type member
enum IpAddr3 {
    V4(u8, u8, u8, u8),
    V6(String),
}

// 4.application
enum Message {
    Quit,
    Move{x: i32, y: i32},
    Write(String),
    Change(i32, i32, i32),
}

impl Message {
    fn print(&self) {
        match *self {
            Message::Quit => println!("Quit"),
            Message::Move{x, y} => println!("Move x = {}, y = {}", x, y),
            Message::Change(a,b ,c ) => println!("Change a= {}, b = {}, c = {}", a, b, c),
            _ => println!("Write"),
            // Error: Message::Write(&s) => println!("Write = {}", s),
        }
    }
}
fn main() {
    let ip4 = IpAddr {
        kind: IpAddKind::V4,
        address: String::from("127.0.0.1"),
    };
    
    let ip6 = IpAddr {
        kind: IpAddKind::V6,
        address: String::from("::1"),
    };

    let ip1 = IpAddr2::V4(String::from("127.0.0.1"));
    let ip2 = IpAddr2::V6(String::from("::1"));

    let _ip1 = IpAddr3::V4(127, 0, 0, 1);
    let _ip2 = IpAddr3::V6(String::from("::1"));

    let quit = Message::Quit;
    quit.print();

    let mo = Message::Move { x: 10, y: 20 };
    mo.print();

    let wri = Message::Write(String::from("Hello Write"));
    wri.print();

    let chang = Message::Change(1, 2, 3);
    chang.print();
    println!("Hello, world!");
}
